package StructurePattern.Decorator;

/**
 * @author: Themberfue
 * @date: 2025/8/12 10:58
 * @description:
 */
// 1. 抽象组件接口 - 定义所有对象的共同接口
interface Component {
    String operation();
}

// 2. 具体组件 - 被装饰的原始对象
class ConcreteComponent implements Component {
    @Override
    public String operation() {
        return "原始对象";
    }
}

// 3. 抽象装饰者 - 实现组件接口并持有组件引用
abstract class Decorator implements Component {
    protected Component component;

    public Decorator(Component component) {
        this.component = component;
    }

    @Override
    public String operation() {
        return component.operation();
    }
}

// 4. 具体装饰者A - 提供额外功能
class ConcreteDecoratorA extends Decorator {
    public ConcreteDecoratorA(Component component) {
        super(component);
    }

    // 新增的功能方法
    private String addFeatureA() {
        return " + 功能A";
    }

    @Override
    public String operation() {
        // 先调用原始对象的方法，再添加新功能
        return super.operation() + addFeatureA();
    }
}

// 5. 具体装饰者B - 提供另一种额外功能
class ConcreteDecoratorB extends Decorator {
    public ConcreteDecoratorB(Component component) {
        super(component);
    }

    // 新增的功能方法
    private String addFeatureB() {
        return " + 功能B";
    }

    @Override
    public String operation() {
        // 先调用原始对象的方法，再添加新功能
        return super.operation() + addFeatureB();
    }
}

// 6. 具体装饰者C - 可以嵌套使用的装饰者
class ConcreteDecoratorC extends Decorator {
    public ConcreteDecoratorC(Component component) {
        super(component);
    }

    // 新增的功能方法
    private String addFeatureC() {
        return " + 功能C";
    }

    @Override
    public String operation() {
        return super.operation() + addFeatureC();
    }
}

// 7. 客户端代码 - 演示装饰者模式的使用
public class DecoratorExample {
    public static void main(String[] args) {
        // 创建原始对象
        Component original = new ConcreteComponent();
        System.out.println("原始对象操作: " + original.operation());

        // 用装饰者A包装原始对象
        Component decoratedA = new ConcreteDecoratorA(original);
        System.out.println("添加功能A后: " + decoratedA.operation());

        // 用装饰者B包装已被装饰的对象
        Component decoratedAB = new ConcreteDecoratorB(decoratedA);
        System.out.println("再添加功能B后: " + decoratedAB.operation());

        // 多层嵌套装饰
        Component fullyDecorated = new ConcreteDecoratorC(
                new ConcreteDecoratorB(
                        new ConcreteDecoratorA(
                                new ConcreteComponent()
                        )
                )
        );
        System.out.println("多层装饰后: " + fullyDecorated.operation());
    }
}

